package com.roamer.school.web.controller;

import com.roamer.school.common.conf.RedisService;
import com.roamer.school.common.exception.enums.ResultCode;
import com.roamer.school.common.exception.suppert.CaptchaErrorException;
import com.roamer.school.common.exception.suppert.UserLogInException;
import com.roamer.school.common.exception.suppert.UserNotLoginException;
import com.roamer.school.common.util.StringUtils;
import com.roamer.school.shiro.util.ShiroUtils;
import com.roamer.school.web.model.ResultBean;
import com.roamer.school.web.model.sys.LoginFrom;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

/**
 * 登陆 控制层
 *
 * @author roamer
 * @version V1.0
 * @date 2018/12/29 14:58
 */
@RestController
public class LoginController {

    @Autowired
    private RedisService redisService;

    /**
     * 处理前台登陆请求
     *
     * @param loginFrom 登陆参数
     *
     * @return {@code ResultBean} 统一数据格式
     *
     * @throws AuthenticationException <ul> 认证异常
     *                                 <li>UnknownAccountException</li>
     *                                 <li>IncorrectCredentialsException</li>
     *                                 <li>LockedAccountException</li>
     *                                 <li>...</li>
     *                                 </ul>
     */
    @PostMapping(value = "/login", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResultBean login(@Valid @RequestBody LoginFrom loginFrom) throws AuthenticationException {
        // 校验验证码
        String captcha = (String) redisService.get(loginFrom.getUuid());
        if (!StringUtils.hasText(captcha) || !captcha.equalsIgnoreCase(loginFrom.getCaptcha())) {
            throw new CaptchaErrorException(ResultCode.CAPTCHA_IS_INVALID);
        }
        // 执行登陆
        try {
            Subject subject = ShiroUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken(loginFrom.getUsername(), loginFrom.getPassword());
            subject.login(token);
        } catch (UnknownAccountException e) {
            throw new UserLogInException(ResultCode.USER_NOT_EXIST);
        } catch (IncorrectCredentialsException e) {
            throw new UserLogInException(ResultCode.USER_PWD_ERROR);
        } catch (LockedAccountException e) {
            throw new UserLogInException(ResultCode.USER_LOCKED_FORBIDDEN);
        }
        return ResultBean.success();
    }

    /**
     * shiro登陆处理，由前台进行路由，只返回状态码
     *
     * @throws UserNotLoginException 用户未登录
     * @see ResultCode#USER_NOT_LOGGED_IN
     */
    @GetMapping(value = "/unLogin")
    public void unLogin() throws UserNotLoginException {
        throw new UserNotLoginException(ResultCode.USER_NOT_LOGGED_IN);
    }

}
